package com.hundsun.cprs.yyt.service.system;

import com.alibaba.fastjson.JSONObject;
import com.hundsun.cprs.yyt.common.base.BaseService;
import com.hundsun.cprs.yyt.common.exception.ServiceCodeException;
import com.hundsun.cprs.yyt.service.system.dto.BankTradeTransRequest;
import com.hundsun.cprs.yyt.service.system.dto.ClearingCenterMessageKey;
import com.hundsun.cprs.yyt.service.system.service.impl.ClearingTradeServiceImpl;
import com.hundsun.cprs.yyt.util.EncryptUtil;
import com.hundsun.cprs.yyt.util.FilesUtil;
import com.hundsun.cprs.yyt.util.HttpClientUtil;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.log4j.Logger;
import org.aspectj.util.FileUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 生成清算中心闭市所需文件
 * @author herong22384
 * @date 20190320
 *
 * */
@Component
public class GeneratorClearingFileService extends BaseService {

    Logger logger = Logger.getLogger(ClearingTradeServiceImpl.class);

    public static final String SEP = "/";
    public static final String LINE = "_";

    @Value("${clearing.file.path}")
    private String clearingFilePath;

    public void generatorClearingFile(String exchangeCode,String authorization,String postUrl,Date tradeDate){
        try{
            SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd");
            String nowDate = sdfDate.format(tradeDate);
            String filePath = clearingFilePath + SEP + nowDate + SEP + exchangeCode;
            String closepriceFileName = nowDate + LINE + exchangeCode + "_closeprice.txt";
            String dealFileName = nowDate + LINE + exchangeCode + "_deal.txt";
            String memberPositionDetailFileName = nowDate + LINE + exchangeCode + "_memberPositionDetail.txt";
            //创建清算文件,并报送文件
            File path = new File(filePath);
            if (!path.exists()){
                path.mkdirs();
            }
            File closePrice = new File(filePath + SEP + closepriceFileName);
            if (!closePrice.exists()){
                closePrice.createNewFile();
                makeMessageAndSend(closePrice,authorization,postUrl,"IB",exchangeCode,tradeDate);
            }
            File dealFile = new File(filePath + SEP + dealFileName);
            if (!dealFile.exists()){
                dealFile.createNewFile();
                makeMessageAndSend(dealFile,authorization,postUrl,"I2",exchangeCode,tradeDate);
            }
            File memberPositionDetailFile = new File(filePath + SEP + memberPositionDetailFileName);
            if (!memberPositionDetailFile.exists()){
                memberPositionDetailFile.createNewFile();
                makeMessageAndSend(memberPositionDetailFile,authorization,postUrl,"I6",exchangeCode,tradeDate);
            }
        }catch (IOException e){
            logger.error("生成清算中心文件出错："+e);
            throw new ServiceCodeException(e.getMessage());
        }catch (Exception e){
            logger.error("生成清算中心文件出错："+e);
            throw e;
        }
    }

    protected Map<String, String> parseParameter(BankTradeTransRequest bankTransRequest,Date tradeDate) {
        Map<String, String> paramMap = new HashMap<String, String>();
        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd");
        //交易日期
        paramMap.put(ClearingCenterMessageKey.KEY_INIT_DATE, sdfDate.format(tradeDate));
        //交易所代码
        paramMap.put(ClearingCenterMessageKey.KEY_EXCHANGE_CODE,bankTransRequest.getExchangeCode());
        //文件类型：I1-客户信息变更文件，I2-成交数据文件，I3-资金余额文件，I4-成交清算文件，I5-持仓汇总文件，I6-持仓明细文件，I7-出入金流
        paramMap.put(ClearingCenterMessageKey.KEY_FILETYPE, bankTransRequest.getFileType());
        //文件存储路径
        paramMap.put(ClearingCenterMessageKey.KEY_FILEPATH, bankTransRequest.getFilePath());
        //文件名称
        paramMap.put(ClearingCenterMessageKey.KEY_FILENAME, bankTransRequest.getFileName());
        //重发标志
        paramMap.put(ClearingCenterMessageKey.KEY_RESEND, "0");//0-否 1-是
        //文件md5码
        paramMap.put(ClearingCenterMessageKey.KEY_FILE_MD5, bankTransRequest.getFileLength());
        //业务时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        paramMap.put(ClearingCenterMessageKey.KEY_BUSI_DATETIME,sdf.format(new Date()));

        paramMap.put("interfacename", "报送文件通知");
        paramMap.put("interfaceno", "file_upload_notify");
        return paramMap;
    }

    protected void sendMessage(Map<String, String> paramMap,String authorization,String postUrl){
        try{
            String responseStr = HttpClientUtil.sendPost(
                    postUrl+"file_upload_notify",
                    paramMap,
                    HttpClientUtil.CHARSET,
                    HttpClientUtil.CHARSET,
                    null,
                    authorization,
                    paramMap.get("interfacename"));
            JSONObject response = JSONObject.parseObject(responseStr);
            if (response.get("data")==null){
                throw new ServiceCodeException(responseStr);
            }
        }catch (ServiceCodeException e){
            logger.error("文件报送失败："+ e);
            throw e;
        }catch (IOException e){
            logger.error("文件报送失败："+ e);
            throw new ServiceCodeException(e.getMessage());
        }
    }

    public void makeMessageAndSend(File file,String authorization,String postUrl,String fileType,String exchangeCode,Date tradeDate){
        try{
            BankTradeTransRequest request = new BankTradeTransRequest();
            request.setExchangeCode(exchangeCode);
            request.setFileName(file.getName());
            request.setFilePath(file.getParent() + File.separator);
            request.setFileType(fileType);
            byte[] fileBytes = FileUtil.readAsByteArray(file);
            String md5 = EncryptUtil.getMD5String(fileBytes);
            request.setFileLength(md5);
            Map<String, String> paramMap = parseParameter(request,tradeDate);
            sendMessage(paramMap,authorization,postUrl);
        }catch (IOException e){
            throw new ServiceCodeException(e.getMessage());
        }
    }
}
